Reactive

响应式编程

基于事件驱动(事件模式,或者订阅者模式),类似于Netty异步事件编程模型.

对不同的事件做不同的处理.所有信息都通过一个编程模型处理.

好处

传统模型相比

  1. JavaWeb开发,基于Servlet. Servlet3.0之前 线程阻塞模型,只有当业务处理完成并返回后时结束Servlet线程.
  2. 3.0规范新特性,支持异步处理-Servlet线程将耗时操作委派给另一个线程完成.在不生成响应的情况下返回至容器.(问题)

Guava的EventBus实现

订阅者模式,观察者模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class EventBusDemo {
@Subscribe
public void sendMessageByMail(String message) {
System.out.println("邮件发送一条信息:" + message);
}

@Subscribe
public void sendMessageByPhone(String message) {
System.out.println("短信发送一条信息:" + message);
}

public static void main(String[] args) {
EventBus eventBus = new EventBus();
eventBus.register(new EventBusDemo());
eventBus.post("hi, boys");
}
}

Mono和Flux常用API

都是数据反应式编程的核心组件.

Reactor是JVM的完全非阻塞响应式编程基础,具有高效的需求管理(以管理”背压”的形式)
它直接与Java 8功能的API,特别是整合CompletableFuture,Stream和 Duration

Flux 相当于一个 RxJava Observable 观察者

WebFlux

Spring WebFlux是随Spring 5推出的响应式Web框架。

Spring WebFlux快速上手——响应式Spring的道法术器

微服务,部署包大小,应用占用内存大小.

Rsocket

用于响应式应用程序的新网络协议(应用层协议).

提供Java,JavaScript,C ++和Kotlin等实现

它是一种基于Reactive Streams背压的双向,多路复用,基于消息的二进制协议

语言无关.

目的

该协议专门设计用于与Reactive风格应用配合使用,这些应用程序基本上是非阻塞的,并且通常(但不总是)与异步行为配对

所谓Reactive背压: 即发布者无法向订户发送数据直到该订户已经准备就绪的想法,这是与“异步”的关键区别。(服务端主动)

问题: 很多个客户端对于同一个消息,准备好的时间层次不一,服务端怎么控制这个(这个消息需要一直保存着吗,什么时候清理).

反应式编程(响应式reactive)是 Java 中高效应用的下一个前沿。但有两个主要障碍 -数据访问和网络。RSocket旨在解决后一个问题,而R2DBC旨在解决前者问题。

响应式应用新协议RSocket

iPhone和Andriod手机,与后端服务交互,提供数据统计,所有这些互动模型,http并不是为此设计.

http. 超文本传输协议,用于从WWW服务器传输超文本到本地浏览器的传输协议。它可以使浏览器更加高效,使网络传输减少.

rest. 基于HTTP的REST服务. restTemplate. 获取http资源, 通过指定的一些格式(json等).

  • 数据统计收集
  • 消息推送
  • 异步响应

RSocket、. Envoy和. Istio

从微服务治理的角度看RSocket、. Envoy和. Istio

重点是把反应流的实现,提升到应用层上来。
其实在底层的协议中,就有反应流的实现,tcp的滑动窗口就是很好的例子。

很大一部分的线上故障是由于阻塞链接造成的.

简单的例子是如果所有的通讯都是反应式的,那就不用容断了.

与http不同的四种交互模式 (重点)

  • Fire-and-Forget
    优化请求/响应,在不需要响应时非常有用,例如非关键事件日志记录。

  • 请求/响应
    当您发送一个请求并收到一个响应时,就像HTTP一样。即使在这里,该协议也具有优于HTTP的优点,因为它是异步和多路复用的。

  • 请求/流
    类似于返回集合的请求/响应,集合被回送而不是查询直到完成,因此例如发送银行帐号,用实时的帐户事务流进行响应。

  • 频道
    允许任意交互模型的双向消息流。

Unix网络编程模型中,底层操作系统的通道都是全双工的,同时支持读写操作.

多路复用的Selector不短的轮询注册在其上的Channel.如果某个Channel上面发生读或者写事件,这个Channel就处于就绪状态,会被Selector轮询出来.然后通过SelectionKey可以获取就绪的Channel的集合,进行后续的I/O操作.

TomcatNio 针对网络IO层面的异步-多路复用.(读写)

Rsocket是交互模式的异步.(或者说Rsocket的请求和响应与Http的请求和响应有什么区别,优点在那里.)

Http的异步通过callBack回调实现.(比如短信交互流程)

客户端使用http发送,短信平台和网关再到运营商都是长链接协议.短信平台受到同一链路上的送达之后.会callBack客户端.客户端收到后,处理回调.如果回调资源处理不当(处理不过来),会导致回调消息丢失. (Rsocket回压场景)

这种http的异步是通过应用程序多次请求实现.再就是客户端层面控制异步. 将请求后的等待丢进线程池或者队列来存储 AsyncCall,然后去做其他的事情.

将 AsycnCall 添加到队列中。将任务交给 Dispatcher 去执行。
比如 OKHTTP实现的异步请求.

  • 使用线程池处理异步任务(这种开销太大,很少做).真正的异步执行者 AsyncCall
  • 使用队列.将 AsycnCall 添加到队列中。将任务交给 Dispatcher 去执行

在使用 Dispatcher 会将 AsyncCall 交给指定的线程去执行,而 AsyncCall 是 NamedRunnable 的子类

OKHTTP异步和同步请求简单分析

Rsocket的异步,理解为没有收到响应,链接保持,但可以做其他事情,受到响应后再做处理.Rsocket天然支持?

深度解读Tomcat中的NIO模型

异步编程:协作性多任务处理